<html>
<head><meta charset="utf-8"><title>slices / vectors in extern &quot;C&quot; · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html">slices / vectors in extern &quot;C&quot;</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="248586101"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248586101" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manuel Drehwald <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248586101">(Aug 06 2021 at 08:54)</a>:</h4>
<p>We recently noticed that slices in extern "C" headers are represented differently:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">extern</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">__enzyme_autodiff</span><span class="p">(</span><span class="n">_</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">a</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">f32</span><span class="p">],</span><span class="w"> </span><span class="n">d_a</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">f32</span><span class="p">]);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">test</span><span class="p">(</span><span class="n">a</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">f32</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="kt">f32</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">//...</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="n">declare</span><span class="w"> </span><span class="n">void</span><span class="w"> </span><span class="o">@</span><span class="n">__enzyme_autodiff</span><span class="p">(</span><span class="kt">i64</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w"> </span><span class="kt">i64</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w"> </span><span class="kt">i64</span><span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="n">unnamed_addr</span><span class="w"> </span>#<span class="mi">3</span><span class="w"></span>
<span class="n">define</span><span class="w"> </span><span class="n">internal</span><span class="w"> </span><span class="n">float</span><span class="w"> </span><span class="o">@</span><span class="n">_ZN4test4test17hcb9908069376019fE</span><span class="p">([</span><span class="mi">0</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">float</span><span class="p">]</span><span class="o">*</span><span class="w"> </span><span class="n">nonnull</span><span class="w"> </span><span class="n">align</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">%</span><span class="n">a</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="kt">i64</span><span class="w"> </span><span class="o">%</span><span class="n">a</span><span class="p">.</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="n">unnamed_addr</span><span class="w"> </span>#<span class="mi">1</span><span class="w"> </span><span class="o">!</span><span class="n">dbg</span><span class="w"> </span><span class="o">!</span><span class="mi">316</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">;</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Why is the compiler generating <code>{ i64, i64 }</code> rather than <code>{ pointer, length }</code> ?<br>
Even if the slice implementation might change, I guess that these two informations must always be available?<br>
At least we stabilized <code>len()</code> and <code>as_ptr()</code> for slice.<br>
Leaving the warning there would be totally fine for me but the current behavior doesn't make sense to me, what reason am I missing?<br>
We generate the implementation of __enzyme_autodiff based on the llvm-ir code of the test function.</p>



<a name="248586492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248586492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248586492">(Aug 06 2021 at 08:59)</a>:</h4>
<p><code>&amp;[T]</code> is not FFI safe. You are only allowed to use it with the unstable rust abi, not the C abi. In this particular case I think the C abi code saw a 2 register big struct and thus casted the value to two register sized integers per the x86_64 System-V abi I think.</p>



<a name="248586765"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248586765" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248586765">(Aug 06 2021 at 09:02)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_target/src/abi/call/x86_64.rs#L59-L76">https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_target/src/abi/call/x86_64.rs#L59-L76</a></p>



<a name="248587797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248587797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manuel Drehwald <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248587797">(Aug 06 2021 at 09:15)</a>:</h4>
<p>Enzyme is an llvm plugin not a rustc plugin, so I think we have to stick to the C abi, rather than the unstable rust abi.<br>
Thanks for the link.<br>
I can understand that it's generally undesired to expose internals.<br>
However, I'm having a hard time understanding why the generation of <code>{ pointer, length }</code> in this case here could be an issue.<br>
Due to already stabilized methods slices must always support this behavior.<br>
There are afaik no cases where the current behavior helps users, but users like Enzyme would benefit from the new information.</p>



<a name="248587967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248587967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248587967">(Aug 06 2021 at 09:17)</a>:</h4>
<p>The problem is that the ABI of slices is not stable. Only the API is stable.</p>



<a name="248640102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248640102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248640102">(Aug 06 2021 at 17:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22/near/248587967">said</a>:</p>
<blockquote>
<p>The problem is that the ABI of slices is not stable. Only the API is stable.</p>
</blockquote>
<p>the diagnostic from <code>improper_ctypes</code> probably should include that detail, right? I mean, sure, the current one (“slices have no C equivalent”), makes sense, but someone who doesn’t realize that the Rust ABI is unstable might make similar inferences to the ones made in the dialogue on this topic.</p>



<a name="248685878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248685878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248685878">(Aug 07 2021 at 01:04)</a>:</h4>
<p><span class="user-mention silent" data-user-id="348574">Manuel Drehwald</span> <a href="#narrow/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22/near/248586101">said</a>:</p>
<blockquote>
<p>Even if the slice implementation might change, I guess that these two informations must always be available?<br>
At least we stabilized <code>len()</code> and <code>as_ptr()</code> for slice.</p>
</blockquote>
<p>You can store two values inside one integer with some cleverness. Cleverness that might be unwise, but nonetheless, the mere presence of a method should not be considered equivalent to a data layout guarantee, and the latter is what an ABI is.</p>



<a name="248687025"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/slices%20/%20vectors%20in%20extern%20%22C%22/near/248687025" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/slices.20.2F.20vectors.20in.20extern.20.22C.22.html#248687025">(Aug 07 2021 at 01:23)</a>:</h4>
<p>I don't think that's practical, though, those tricks can be... academic. A more practical example: an ABI guarantee would prevent storing those values but in an "out of band" fashion. I could see that being made to happen for the length in cases where the slice started life as a pointer to an array.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>